/**
 * Author shuqi
 * Rev
 * Date: 2019-12-13 10:38
 * <p>
 * Copyright (C) 2019 Seeyon, Inc. All rights reserved.
 * <p>
 * This software is the proprietary information of Seeyon, Inc.
 * Use is subject to license terms.
 * @company seeyon.com
 * @since V5 V8.0
 * @author shuqi
 */
package com.shuqi.tools.utils;

import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.apache.commons.compress.utils.IOUtils.closeQuietly;

/**
 * @description
 * @date 2019-12-13 10:38
 * @since V5 V8.0
 * @author shuqi
 */
public class HttpUtils {

	private static Map<String,String> defaultHead = new HashMap<>();
	static {
		// 设置通用的请求属性
		defaultHead.put("accept", "*/*");
		defaultHead.put("connection", "Keep-Alive");
		defaultHead.put("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36");
		defaultHead.put("Accept-Language", "en,zh-CN;q=0.9,zh;q=0.8");
	}


	public static String get(String surl){
		BufferedReader in = null;
		try {
			HttpURLConnection con = (HttpURLConnection)openConnect(surl);
			con.setInstanceFollowRedirects(false);
			con.connect();

			in = new BufferedReader(new InputStreamReader(con.getInputStream(),"utf-8"));
			String line;
			String result = "";
			while ((line = in.readLine()) != null) {
				result += line;
			}
			return result;
		}catch (Exception e){
			throw new RuntimeException(e.getLocalizedMessage());
		}finally {
			closeQuietly(in);
		}
	}
	public static Response post(String surl,String body,Map<String,String> headrs){
		BufferedReader in = null;
		try {
			HttpURLConnection con = (HttpURLConnection)openConnect(surl);
			con.setInstanceFollowRedirects(false);// 阻止重定向
			if(headrs != null){
				for (Map.Entry<String, String> stringStringEntry : headrs.entrySet()) {
					con.setRequestProperty(stringStringEntry.getKey(),stringStringEntry.getValue());
				}
			}

			con.setDoInput(true);
			con.setDoOutput(true);
			con.connect();

			OutputStream out = con.getOutputStream();
			out.write(body.getBytes());
			out.flush();


			in = new BufferedReader(new InputStreamReader(con.getInputStream(),"utf-8"));
			String line;
			StringBuilder result = new StringBuilder();
			while ((line = in.readLine()) != null) {
				result.append("\n").append(line);
			}
			return new Response(result.toString(),con.getHeaderFields());
		}catch (Exception e){
			LoggerUtils.error(e.getLocalizedMessage(),e);
			throw new RuntimeException(e.getLocalizedMessage());
		}finally {
			closeQuietly(in);
		}
	}
	public static Response post(String surl,Map<String,Object> params) throws Exception {
		List<String> paramss = new ArrayList<>();

		for (Map.Entry<String, Object> stringObjectEntry : params.entrySet()) {
			paramss.add(stringObjectEntry.getKey() + "=" + URLEncoder.encode(stringObjectEntry.getValue().toString(), "utf-8"));
		}
		return post(surl, StringUtils.join(paramss, "&"), null);
	}
	public static Response post(String surl,Map<String,Object> params,Map<String,String> headrs) throws Exception {
		List<String> paramss = new ArrayList<>();

		for (Map.Entry<String, Object> stringObjectEntry : params.entrySet()) {
			paramss.add(stringObjectEntry.getKey() + "=" + URLEncoder.encode(stringObjectEntry.getValue().toString(), "utf-8"));
		}
		return post(surl, StringUtils.join(paramss, "&"), headrs);
	}
	/**
	 * 打开链接
	 * @param surl
	 * @return
	 */
	@NotNull
	private static URLConnection openConnect(String surl) throws Exception {
		if(surl.startsWith("https://")){
			HttpsURLConnection.setDefaultHostnameVerifier(defaultHostnameVerifier);
			HttpsURLConnection con = (HttpsURLConnection)new URL(surl).openConnection();
			// 设置默认的请求头
			for (Map.Entry<String, String> stringStringEntry : defaultHead.entrySet()) {
				con.setRequestProperty(stringStringEntry.getKey(),stringStringEntry.getValue());
			}
			con.setConnectTimeout(10000);
			con.setReadTimeout(50000);

			// Prepare SSL Context
			TrustManager[] tm = { defaultCertificationTrustManger };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			con.setSSLSocketFactory(sslContext.getSocketFactory());
			return con;
		}else{
			return new URL(surl).openConnection();
		}
	}


	private static TrustManager defaultCertificationTrustManger = new X509TrustManager() {
		private X509Certificate[] certificates;
		public void checkClientTrusted(X509Certificate certificates[],String authType) {
			if (this.certificates == null) {
				this.certificates = certificates;
			}

		}
		public void checkServerTrusted(X509Certificate[] ax509certificate,  String s) {
			if (this.certificates == null) {
				this.certificates = ax509certificate;
			}
		}
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	};
	/**
	 * 忽视证书HostName
	 */
	private static HostnameVerifier defaultHostnameVerifier = new HostnameVerifier() {
		public boolean verify(String s, SSLSession sslsession) {
			return true;
		}
	};


	public static class Response{
		private String body;
		private Map<String, List<String>> headers;

		public String getBody() {
			return body;
		}

		public void setBody(String body) {
			this.body = body;
		}

		public Map<String, List<String>> getHeaders() {
			return headers;
		}

		public void setHeaders(Map<String, List<String>> headers) {
			this.headers = headers;
		}

		public Response(String body, Map<String, List<String>> headers) {
			this.body = body;
			this.headers = headers;
		}

		public Response() {
		}
	}
}
